const Controller = require('egg').Controller;

/**
 * socket.id 连接ID
 * socket.handshake.query 连接参数
 */

/**
* 缓存所有的连接
*/
const users = {};

class ChatController extends Controller {
  /**
   * 上线通知
   * 2020-03-09
   */
  async online() {
    const { ctx, app, service } = this;
    const message = ctx.args[0] || {};
    const socket = ctx.socket;
    const { payload } = message;
    users[payload.userId] = socket.id;
    const chat = app.io.of('/');

    // 初始化聊天列表
    let list = await service.chat.getChatList2({ user_id: payload.userId });
    list = list.data.list;
    chat.to(users[payload.userId]).emit('chat-list', {
      payload: {
        list
      }
    });

    // 初始化各聊天的消息
    for(let index = 0; index < list.length; index++) {
      const newsList = await service.chat.getMsgFromPartner(payload.userId, list[index].partner_id, list[index].is_group);
      chat.to(users[payload.userId]).emit('chat-item-list', {
        payload: {
          list: newsList,
          partner_id: list[index].partner_id,
          is_group: list[index].is_group,
        }
      });
    }

    {
      // 初始化聊天列表
      let list = await service.ack.list({ user_id: payload.userId });
      chat.to(users[payload.userId]).emit('init-ack', {
        payload: {
          list
        }
      });
    }
  }

  /**
   * @description 私发消息
   * 1. 向消息表中插入记录
   * 2. 向发送者和接收者push消息, 向发送者push是因为前端要确人是否发送成功
   * 2020-03-09
   */
  async news() {
    const { ctx, app, service } = this;
    const message = ctx.args[0] || {};
    const chat = app.io.of('/');
    try {
      const { payload } = message;
      // 发送者
      const s_user = await service.chat.getUserInfo({ user_id: payload.s_user });
      // 接收者
      const r_user = await service.chat.getUserInfo({ user_id: payload.r_user });
      // 创建消息
      const msg = await service.chat.create({
        s_user: payload.s_user,
        r_user: payload.r_user,
        content: payload.content,
        avatar: payload.avatar,
        nickname: payload.nickname
      });
      // 向发送者 push 消息
      chat.to(users[msg.s_user]).emit('news', {
        payload: {
          ...msg,
          partner_id: msg.r_user
        }
      });
      // 向接收者 push 消息
      chat.to(users[msg.r_user]).emit('news', {
        payload: {
          ...msg,
          partner_id: msg.s_user
        }
      });
    } catch (error) {
      app.logger.error(error);
    }
  }

  /**
   * 讨论组
   */
   async roomNews() {
    const { ctx, app, service } = this;
    const message = ctx.args[0] || {};
    const chat = app.io.of('/');
    try {
      const { payload } = message;
      // 发送者
      const s_user = await service.chat.getUserInfo({ user_id: payload.s_user });

      const res = await service.chat.create({
        s_user: payload.s_user,
        r_user: payload.r_user,
        content: payload.content,
        room_id: payload.room_id,
        is_group: 1,
        avatar: payload.avatar,
        nickname: payload.nickname
      });

      let allUser = await service.room.getRoomUserList({
        roomId: payload.room_id
      });

      allUser = JSON.parse(JSON.stringify(allUser))

      console.log(allUser, 1111)

      allUser.forEach(element => {
        if (users[element.user_id]) {
          chat.to(users[element.user_id]).emit('room-news', {
            payload: {
              ...res,
              nickname: s_user.nickname,
              avatar: s_user.avatar,
              partner_id: res.r_user,
              allUser
            }
          });
        }
      });
    } catch (error) {
      app.logger.error(error);
    }
  }

  async receiveAllMsg () {
    const { ctx, app, service } = this;
    const chat = app.io.of('/');
    const socket = ctx.socket;
    const message = ctx.args[0] || {};
    const client = socket.id;
    const query = socket.handshake.query;

    const { target, payload } = message;

    const uid = await service.user.getUserIdByToken(query.token);
    const ret = await service.chat.index({ uid });

    try {
      chat.emit(target, {
        payload: payload,
        uid,
        ...ret.data
      });
    } catch (error) {
      app.logger.error(error);
    }
  }

  /**
   * 好友申请
   */
  async friendApply() {
    const { ctx, app, service } = this;
    const message = ctx.args[0] || {};
    const chat = app.io.of('/');
    try {
      const { payload } = message;
      const res = await service.friend.createFriendApply({
        s_user: payload.s_user,
        r_user: payload.r_user,
        remark: payload.remark
      });
      // 发送者
      const s_user = await service.chat.getUserInfo({ user_id: payload.s_user });
      // 向接收者 push 消息
      chat.to(users[payload.r_user]).emit('friendApply', {
        payload: {
          ...res,
          nickname: s_user.nickname,
          avatar: s_user.avatar,
        }
      });
    } catch (error) {
      app.logger.error(error);
    }
  }

  async dealFriendApply() {
    const { ctx, app, service } = this;
    const message = ctx.args[0] || {};
    const chat = app.io.of('/');
    console.log(111)
    try {
      const { payload } = message;
      const detail = await service.friend.getFriendApplyDetail({ id: payload.id });
      const res = await service.friend.dealFriendApply({ id: payload.id, status: payload.status });

      console.log(detail)

      if (payload.status == 0) {
        // 同意
        const info = await service.friend.createFriend({ uid: detail.s_user, eid: detail.r_user });

        // 发送者
        // const s_user = await service.chat.getUserInfo({ user_id: detail.s_user });

        // 接收者
        const r_user = await service.chat.getUserInfo({ user_id: detail.r_user });

        // 向接收者 push 消息
        chat.emit('new-friend', {
          payload: {
            // ...res,
            ...info,
            nickname: r_user.nickname,
            avatar: r_user.avatar,
          }
        });
      }
    } catch (error) {
      app.logger.error(error);
    }
  }

  /**
   * 消息已读回执
   */
  async ack() {
    const { ctx, app, service } = this;
    const message = ctx.args[0] || {};
    const chat = app.io.of('/');
    try {
      const { payload } = message;
      const record = await service.ack.create({
        user_id: payload.user_id,
        ack_time: payload.ack_time,
        partner_id: payload.partner_id
      });
      // 向发送者 push 消息
      chat.to(users[payload.user_id]).emit('ack', {
        payload: record
      });
    } catch (error) {
      app.logger.error(error);
    }
  }
}

module.exports = ChatController;
